package com.example.mygame.utils;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;

public class JsonUtils {

    // 单例 Gson 实例（线程安全）
    private static final Gson GSON;

    static {
        // 初始化 Gson 并配置常用选项
        GSON = new GsonBuilder()
                .setPrettyPrinting() // 格式化输出（仅影响序列化）
                .serializeNulls()    // 序列化时包含 null 值
                .disableHtmlEscaping() // 禁止 HTML 转义
                .create();
    }

    /**
     * 从 JSON 字符串解析为对象
     * @param json JSON 字符串
     * @param clazz 目标类
     * @return 解析后的对象
     */
    public static <T> T fromJson(String json, Class<T> clazz) {
        if (json == null || json.isEmpty()) {
            return null;
        }
        return GSON.fromJson(json, clazz);
    }

    /**
     * 从 JSON 字符串解析为泛型对象（如 List<T>、Map<K,V>）
     * @param json JSON 字符串
     * @param type 泛型类型（使用 TypeToken 获取）
     * @return 解析后的泛型对象
     */
    public static <T> T fromJson(String json, Type type) {
        if (json == null || json.isEmpty()) {
            return null;
        }
        return GSON.fromJson(json, type);
    }

    /**
     * 从 JSON 文件解析为对象
     * @param filePath 文件路径
     * @param clazz 目标类
     * @return 解析后的对象
     * @throws IOException 读取文件异常
     */
    public static <T> T fromJsonFile(String filePath, Class<T> clazz) throws IOException {
        String json = new String(Files.readAllBytes(Paths.get(filePath)), StandardCharsets.UTF_8);
        return fromJson(json, clazz);
    }

    /**
     * 从 JSON 文件解析为泛型对象
     * @param filePath 文件路径
     * @param type 泛型类型
     * @return 解析后的泛型对象
     * @throws IOException 读取文件异常
     */
    public static <T> T fromJsonFile(String filePath, Type type) throws IOException {
        String json = new String(Files.readAllBytes(Paths.get(filePath)), StandardCharsets.UTF_8);
        return fromJson(json, type);
    }

    /**
     * 从输入流解析为对象
     * @param inputStream 输入流
     * @param clazz 目标类
     * @return 解析后的对象
     * @throws IOException 流操作异常
     */
    public static <T> T fromJson(InputStream inputStream, Class<T> clazz) throws IOException {
        try (Reader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8)) {
            return GSON.fromJson(reader, clazz);
        }
    }

    /**
     * 解析 JSON 为 List 集合
     * @param json JSON 字符串
     * @param clazz 集合元素类型
     * @return List 集合
     */
    public static <T> List<T> fromJsonToList(String json, Class<T> clazz) {
        Type type = TypeToken.getParameterized(List.class, clazz).getType();
        return fromJson(json, type);
    }

    /**
     * 解析 JSON 为 Map 集合
     * @param json JSON 字符串
     * @param keyClazz 键类型
     * @param valueClazz 值类型
     * @return Map 集合
     */
    public static <K, V> Map<K, V> fromJsonToMap(String json, Class<K> keyClazz, Class<V> valueClazz) {
        Type type = TypeToken.getParameterized(Map.class, keyClazz, valueClazz).getType();
        return fromJson(json, type);
    }

    /**
     * 将对象序列化为 JSON 字符串（辅助方法）
     * @param obj 要序列化的对象
     * @return JSON 字符串
     */
    public static String toJson(Object obj) {
        return GSON.toJson(obj);
    }

    /**
     * 将对象序列化并保存到 JSON 文件（辅助方法）
     * @param obj 要序列化的对象
     * @param filePath 保存路径
     * @throws IOException 写入文件异常
     */
    public static void toJsonFile(Object obj, String filePath) throws IOException {
        String json = toJson(obj);
        Files.write(Paths.get(filePath), json.getBytes(StandardCharsets.UTF_8));
    }

    /**
     * 获取 Gson 实例（用于自定义配置）
     * @return Gson 实例
     */
    public static Gson getGson() {
        return GSON;
    }
}
